﻿using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace FunstreamTV.Tools
{
    public static class MultiRegexpParser
    {
        public static List<RegexpResult> Parse(string Input, string[] ExpressionList)
        {
            return split(Input, ExpressionList);
        }

        /// <summary>
        /// Рекурсивка которая делит текст на куски по регулярке, а потом куски ну кускт по след. регулярке и так далее
        /// </summary>
        /// <param name="Content">входная строка</param>
        /// <param name="Expression">список регулярок</param>
        /// <param name="depth">глубина рекурсии</param>
        /// <returns></returns>
        private static List<RegexpResult> split(string Content, string[] Expression, int depth = 0)
        {
            List<RegexpResult> result = new List<RegexpResult>();

            // на максимальной глубине совпадений по регуляркам быть уже не может, по этому возвращаем текст без парсинга
            if (depth == Expression.Count())
            {
                result.Add(new RegexpResult(Content, null, -1, RegexpResultType.Text));
                return result;
            }

            // режем текст на куски по регулярке,
            // и находим сами совпадения 

            var text = Regex.Split(Content, Expression[depth]);
            var matches = Regex.Matches(Content, Expression[depth]);

            // запускаем рекурсию на каждый кусок текста, увеличивая глубину                        
            if (matches.Count > 0)
            {
                for (int i = 0; i < matches.Count; i++)
                {
                    result.AddRange(split(text[i], Expression, depth + 1));
                    result.Add(new RegexpResult(matches[i].Value, matches[i], depth, RegexpResultType.Match));
                }
                result.AddRange(split(text.Last(), Expression, depth + 1));
            }
            else
            {
                result.AddRange(split(Content, Expression, depth + 1));
            }
            return result;
        }

    }

    public class RegexpResult
    {
        public RegexpResult(string Value, Match ExpMatch, int ExpressionNumber, RegexpResultType Type)
        {
            this.Value = Value;
            this.ExpressionId = ExpressionNumber;
            this.Type = Type;
            this.ExpMatch = ExpMatch;

        }
        /// <summary>
        /// Текст
        /// </summary>
        public readonly string Value;
        /// <summary>
        /// Идентификатор регулярки, соответстует номеру в списке регулярок который был передан в Parse();
        /// </summary>
        public readonly int ExpressionId;
        /// <summary>
        /// Объект Match, есть только у элеметов совпадения регулярок
        /// </summary>
        public readonly Match ExpMatch;
        /// <summary>
        /// Тип элемента - текст, или совпадение регулярки
        /// </summary>
        public readonly RegexpResultType Type;
    }


    public enum RegexpResultType
    {
        Text, // Простой текст
        Match // Результат совпадения
    }
}
